package ar.edu.itba.it.cg.grupo01.impl;

import java.util.ArrayList;
import java.util.List;

import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;

import ar.edu.itba.it.cg.grupo01.impl.shape.MathPlane;

import static com.google.common.base.Preconditions.*;

public class Utilities {

	/**
	 * Check if a list of points are on the same plane.
	 * @param points
	 * @return
	 */
	public static boolean pointsOnSamePlane (List<Point3d> points) {
				
		// check arguments
		checkArgument(points.size() >= 3, "At least 3 points are needed to define a plane");
		//TODO check point are not the same
		
		
		// calculate plane equation [
		Vector3d dir1 = new Vector3d(points.get(0));
		Vector3d dir2 = new Vector3d(points.get(0));
		dir1.sub(points.get(1));
		dir2.sub(points.get(2));
		
		Vector3d normal = new Vector3d();
		normal.cross(dir1, dir2);
		
		MathPlane plane = new MathPlane(points.get(0), normal);
		
		for (Point3d point : points) {
			if (!plane.contains(point))
				return false;
			
		}

		return true;
	}
	
	/**
	 * Returns a list with the first element as the vertex with the right angle if the points
	 * form a right triangle or null otherwise.
	 * @param a
	 * @param b
	 * @param c
	 * @return
	 */
	public static List<Point3d> pointsFormRightTriangle(Point3d a, Point3d b, Point3d c) {
		
		Vector3d v1 = new Vector3d(a);
		Vector3d v2 = new Vector3d(b);
		Vector3d v3 = new Vector3d(c);
		
		v1.sub(b);
		v2.sub(c);
		v3.sub(a);
		
		List<Point3d> points = new ArrayList<Point3d>();
		if (Math.abs(v1.dot(v2)) < Precision.EPSILON) {
			points.add(b);
			points.add(c);
			points.add(a);
			return points;
		}
		
		if (Math.abs(v2.dot(v3)) < Precision.EPSILON) {
			points.add(c);
			points.add(a);
			points.add(b);
			return points;
		}
		
		if (Math.abs(v3.dot(v1)) < Precision.EPSILON) {
			points.add(a);
			points.add(b);
			points.add(c);
			return points;
		}
		
		return null;
	}
}
